-----------The Function Game-----------
A 4am crack                  2018-11-30
---------------------------------------

Name: The Function Game
Genre: educational
Year: 1983
Credits: Ed Zeidman, Ph.D.
Publisher: MUSE Software
Platform: Apple ][+ or later
Media: 5.25-inch disk
Sides: 1
OS: DOS 3.3
Previous cracks: none
Similar cracks:
  #678 Antonym Antics
  #497 The Eating Machine

                   ~

               Chapter 0
 In Which Various Automated Tools Fail
          In Interesting Ways


COPYA
  immediate disk read error, but it
  earns a participation trophy just for
  showing up

Locksmith Fast Disk Backup
  can read some of track $00 (but not
  sector $08 or $0F), all of tracks $01
  and $02, then nothing else

EDD 4 bit copy (no sync, no count)
  works

Passport
  unable to capture RWTS
  tries to use built-in RWTS and fails

Copy ][+ nibble editor
  tracks $03+ use modified address
  prologue "D5 DA 96", data prologue
  "D5 DA AD", data epilogue "DE DA AB"

Disk Fixer
  ["O" -> "Input/Output Control"]
    set Address Prologue to "D5 DA 96"
    set Data Prologue to "D5 DA 96"
    set Data Epilogue to "D5 DA 96"
  Success! Tracks 3+ readable!
  But they look a little bit weird...
  Possibly a modified nibble translate
  table?

                 --v--

-------------- DISK EDIT --------------
TRACK $11/SECTOR $0F/VOLUME $01/BYTE$00
---------------------------------------
$00:>24<35 2A 24 24 24 24 24   $5*$$$$$
$08: 24 24 24 27 2B 26 EC E1   $$$'+&la
$10: E8 E8 E9 86 86 86 86 86   hhi.....
$18: 86 86 86 86 86 86 86 86   ........
$20: 86 86 86 86 86 86 86 86   ........
$28: 86 86 86 86 21 26 25 2E   ....!&%.
$30: 24 E5 E0 86 86 86 86 86   $e`.....
$38: 86 86 86 86 86 86 86 86   ........
$40: 86 86 86 86 86 86 86 86   ........
$48: 86 86 86 86 86 86 86 3E   .......>
$50: 26 22 26 26 E2 83 84 E2   &"&&b..b
$58: ED E8 E1 84 84 84 84 84   mha.....
$60: 84 84 84 84 84 84 84 84   ........
$68: 85 85 85 85 85 85 85 85   ........
$70: 85 85 27 25 20 2B 27 E3   ..'% +'c
$78: E2 85 85 85 85 85 85 85   b.......

                 --^--

Why didn't COPYA work?
  modified prologues and epilogues

Why didn't Locksmith FDB work?
  modified prologues and epilogues

EDD worked. What does that tell us?
  no half or quarter tracks
  almost certainly no nibble check
  (just structural changes to epilogue)

Next steps:

  1. capture RWTS
  2. convert disk to standard format
     with Advanced Demuffin
  3. patch RWTS to read standard format
  4. declare victory (*)

(*) go to the gym

                   ~

               Chapter 1
In Which We Attempt To Use The Original
    Disk As A Weapon Against Itself
    And It Does Not Go At All Well


Given the lack of support in Passport,
I am left with the tools I made for
myself in the pre-Passport era: a work
disk in slot 5, the original in slot 6,
and some funky scripts to automate as
much of the process as possible.

[S6,D1=original disk]
[S6,D2=blank disk]
[S5,D1=my work disk]

]PR#5
CAPTURING BOOT0
...reboots slot 6...
...reboots slot 5...
SAVING BOOT0
CAPTURING BOOT1
...reboots slot 6...
...reboots slot 5...
SAVING BOOT1
SAVING RWTS

That was suspiciously easy. Well, let's
load up the RWTS it captured and try to
use it to read the original disk.

]BRUN ADVANCED DEMUFFIN 1.5

["5" to switch to slot 5]

["R" to load a new RWTS module]
  --> At $B8, load "RWTS" from drive 1

["6" to switch to slot 6]

["C" to convert disk]

[<Return> to start conversion]

...Advanced Demuffin crashes...

Wait, what?

                   ~

               Chapter 2
        In Which We Muse On The
    Pluralization Of Made-Up Words


]PR#5
...hold down <Esc> key during boot so
   Diversi-DOS doesn't relocate to the
   language card...

I'll leave the standard RWTS (on my
work disk) at $B800 and load the
original disk's RWTS at $3800. Then I
can use standard monitor commands to
compare them.

]BLOAD RWTS,A$3800
]CALL -151

The entry point that Advanced Demuffin
calls is $BD00, so let's start there.

*3D00<BD00.BDFFV

BD95-5A (E7)
BD96-BE (BC)
BDA4-4E (46)
BDBD-30 (7F)

Aha! Four differences, just in the
$BD00..$BDFF range alone.

*3D90L

3D90-   A0 04       LDY   #$04
3D92-   B1 48       LDA   ($48),Y
3D94-   20 E7 BC    JSR   $BCE7   <-- ?
3D97-   28          PLP
3D98-   D0 11       BNE   $3DAB

According to "Beneath Apple DOS," this
code (normally at $BD90) will "get
destination track and go to it using
MYSEEK subroutine at $BE5A." [p. 8-38]
But instead of $BE5A, we're calling
$BCE7 instead, which is normally unused
space.

*3CE7L

; save track number (in accumulator)
3CE7-   48          PHA

; track > 3?
3CE8-   C9 03       CMP   #$03

; yes, branch
3CEA-   B0 04       BCS   $3CF0

; no, track is 0-2
3CEC-   A9 AA       LDA   #$AA
3CEE-   D0 02       BNE   $3CF2
3CF0-   A9 DA       LDA   #$DA

; uh oh
3CF2-   20 B6 B6    JSR   $B6B6
3CF5-   A9 0E       LDA   #$0E
3CF7-   8D 55 B6    STA   $B655
3CFA-   68          PLA
3CFB-   4C 5A BE    JMP   $BE5A

Without even investigating the routine
at $B6B6 (which I will, don't worry),
I can tell you why Advanced Demuffin
crashed. This RWTS is calling a custom
routine outside the $B800..$BFFF range.
It's not self-contained like most RWTSs
are(*). If you boot the original disk,
T00,S00 is reloaded at $B600, so it's
available for whatever. (Even later
versions of DOS 3.3 use it for code
patches.)

(*) After almost 2000 write-ups, I have
    given up hope of every finding a
    plural of "RWTS" that doesn't make
    my skin crawl.

I have the code at $B600; it's in the
"BOOT1" file that my AUTOTRACE script
saved to my work disk.

*BLOAD BOOT1,A$3600
*36B6L

; make a bunch of adjustments to the
; prologues and epilogues
36B6-   8D 58 B8    STA   $B858
36B9-   8D A3 B8    STA   $B8A3
36BC-   8D F1 B8    STA   $B8F1
36BF-   8D 3F B9    STA   $B93F
36C2-   8D 5F B9    STA   $B95F
36C5-   8D 7F BC    STA   $BC7F

; and an adjustment to the nibble
; translate table
36C8-   49 70       EOR   #$70
36CA-   8D 4C BA    STA   $BA4C
36CD-   60          RTS

(This final adjustment is why sectors
looked "weird" in the disk editor, even
after correcting for the address and
data prologue and epilogue changes.)

The solution is simple: use the "BOOT1"
file instead of the "RWTS" file in
Advanced Demuffin.

*BRUN ADVANCED DEMUFFIN 1.5

["5" to switch to slot 5]

["R" to load a new RWTS module]
  --> At $B6, load "BOOT1" from drive 1

["6" to switch to slot 6]

["C" to convert disk]

                 --v--

ADVANCED DEMUFFIN 1.5    (C) 1983, 2014
ORIGINAL BY THE STACK    UPDATES BY 4AM
=======PRESS ANY KEY TO CONTINUE=======
TRK:R..................................
+.5:
    0123456789ABCDEF0123456789ABCDEF012
SC0:...................................
SC1:...................................
SC2:...................................
SC3:...................................
SC4:...................................
SC5:...................................
SC6:...................................
SC7:...................................
SC8:R..................................
SC9:...................................
SCA:...................................
SCB:...................................
SCC:...................................
SCD:...................................
SCE:...................................
SCF:R..................................
=======================================
16SC $00,$00-$22,$0F BY1.0 S6,D1->S6,D2

                 --^--

Oh what fresh hell is this.

                   ~

               Chapter 3
    In Which We Briefly Investigate
        What Fresh Hell This Is


]PR#5
]CATALOG,S6,D2

]CATALOG,S6

C1983 DSR^C#254
055 FREE

 A 007 HELLO
 A 024 CF
 T 002 D% FILE
 A 058 FG
 T 006 FG MESSAGES
 T 002 FG OPTIONS
 A 047 FH
 T 020 FN FILE
 T 002 FUNCTION SELECTION
 T 092 HINT FILE
 A 047 INTRO
 A 012 MAIN
 T 002 MENU OPTIONS
 A 042 PF
 A 014 SF
 A 039 SYSTEM
 B 008 ^HISUBS
 B 003 ^MX-80
 B 002 ^PR
 B 002 ^SUBS
 B 002 ^Z
 B 003 MUSE !!
 B 003 SCRUNCH
 B 002 ONETWO

]RUN HELLO
...boots as far as the main menu at
   least...

OK, my copy does not appear to use the
two sectors I can't read. That's good.
That narrows the scope considerably.

]PR#5
]BLOAD BOOT0,A$800
]CALL -151
.
. poke, poke, poke...
.

Aha! Here's the problem.

*84D.85C

084D-                00 0D 0B
0850- 09 07 05 03 01 02 0C 0A
0858- 08 06 04 02 0F

This is the mapping of physical to
logical sectors. It's used by boot0 to
load boot1 from sectors 9 through 0.
Notice anything odd? $02 is listed
twice!

Turning to my trusty Disk Fixer sector
editor and looking at track 0 of the
original disk, I see that the code I
would expect to see on sector 8 (which
is loaded into $BE00..$BEFF) is
actually on sector $0E! Because of the
duplicate $02 in the physical/logical
sector mapping in boot0, the original
disk ignores logical sector 8 and
instead loads that code from logical
sector $0E.

But what about sector $0F? Surely that
is used to hold part of boot2. On a
standard DOS 3.3 disk, DOS is loaded
backwards from T02,S04 down to T00,S0D,
so T00,S0F would be loaded at $9F00.
But on this disk, it is not. Why?

]PR#5
]BLOAD BOOT1,A$2600
]CALL -151
*B700<2700.27FFM
*B700L

B700-   8E E9 B7    STX   $B7E9
B703-   8E F7 B7    STX   $B7F7
B706-   A9 01       LDA   #$01
B708-   8D F8 B7    STA   $B7F8
B70B-   8D EA B7    STA   $B7EA
B70E-   AD E0 B7    LDA   $B7E0
B711-   8D E1 B7    STA   $B7E1
B714-   A9 02       LDA   #$02
B716-   8D EC B7    STA   $B7EC
B719-   A9 0A       LDA   #$0A    <-- !
B71B-   8D ED B7    STA   $B7ED
B71E-   AC E7 B7    LDY   $B7E7
B721-   88          DEY
B722-   8C F1 B7    STY   $B7F1

Aha! DOS is loaded starting from
T02,S0A (instead of T02,S04). So it
never gets as far as T00,S0F, so the
fact that that sector doesn't exist
does not pose any existential threat.

Some days, I wish it were enough just
to bypass the protection instead of so
meticulously understanding it.

[S6,D1=demuffin'd disk]

]PR#6
...loads DOS then grinds and exits with
   an I/O error...

Of course, the converted disk can't
read itself, because it still has that
RWTS swapping code at $B6B6. Let's
neuter that.

T00,S00,$B6 change 8D to 60

]PR#6
...works...

Quod erat liberandum.

                   ~

               Epilogue


For the sort of people who would read
this far into a crack write-up in 2018,
here's a bonus question: why were my
pre-Passport AUTOTRACE scripts able to
capture the RWTS on this disk, but
Passport itself couldn't?

The answer lies in the sector order map
and that pesky duplicated sector 2. To
work with thousands of disks without
crashing or producing invalid output,
Passport is more conservative than my
previous generation of scripts. To that
end, it intentionally checks the sector
order map in the boot sector before it
decides whether it is safe to use the
original disk's RWTS.

Here is the relevant code from
passport/src/id/dos33.a:

                 --v--

;
; Sector order map must be standard (no
; exceptions)
;
  lda   #$00
  ldx   #$4D
  ldy   #$10
  jsr   compare    ; if T00,S00,$4D ==
  !byte $00,$0D,$0B,$09,$07,$05,$03,$01
  !byte $0E,$0C,$0A,$08,$06,$04,$02,$0F
  bcs   .exit

                 --^--

In the general case, a non-standard
sector order map in the boot sector
means there is a matching non-standard
sector order map elsewhere in the RWTS.
Using the original RWTS to read, but a
standard RWTS to write, would remap the
sectors to a standard mapping and
require a patch to the RWTS's sector
order map before the converted disk
could read itself. This second sector
order map is not always in the same
place (!@#$%^). Out of an abundance of
caution, I added the extra check in
Passport to skip capturing the disk's
RWTS if the boot sector's map is non-
standard.

On this disk, this check turns out to
be unnecessary. The RWTS has a standard
sector order map that it uses for all
tracks except track 0, and it never
reads track 0 because DOS is shifted
several sectors and fits entirely on
tracks 1 and 2. But Passport doesn't
yet support this combination of edge
cases, so it decides not to capture the
RWTS and tries to read the disk without
it (which fails for different reasons).

If Passport had been available during
the 1980s, this is the sort of edge
case that copy protection developers
would have exploited to keep their
disks from being cracked just a few
weeks longer -- as they did against bit
copiers, over and over. I think about
that a lot.

---------------------------------------
A 4am crack                    No. 1922
------------------EOF------------------
